package cn.jdy.framework.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 手动静态获取bean对象工具类
 * 
 * @author wangensh
 * @version 1.0
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {

  // spring 容器上下文对象
  private static ApplicationContext ctx = null;

  public void setApplicationContext(ApplicationContext context) throws BeansException {
    ctx = context;
  }

  public static ApplicationContext getApplicationContext() throws BeansException {
    checkApplicationContext();
    return ctx;
  }

  /**
   * 根据bean的class来查找对象
   * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
   * tips: 由于通过class的方式不能获取到bean，此处通过转换类名，将首字母小写的方式，通过name获取bean
   * 通过class 获取的好处是 类名的变更会有语法检测，通过ide提示相关代码的调整
   * @param Class
   * @return T
   */
  public static <T> T getBean(Class c){
    checkApplicationContext();
    String str = c.getSimpleName();
    String name = str.replaceAll("^.{1}", str.substring(0,1).toLowerCase());
    return (T) ctx.getBean(name);
  }
  
  /**
   * 按照name的方式获取bean，已过时，建议使用getBean(Class c)
   * @param name
   * @return
   */
  @Deprecated
  public static <T> T getBean(String name){
    checkApplicationContext();
    return (T) ctx.getBean(name);
  }
  
  /**
   * 清除applicationContext静态变量.
   */
  public static void cleanApplicationContext() {
    ctx = null;
  }

  private static void checkApplicationContext() {
    if (ctx == null) {
      throw new IllegalStateException(
          "applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
    }
  }
}
